﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using DailyReport.Helpers;
using DailyReport.Models;
using MyHelpers;
using Newtonsoft.Json;

namespace DailyReport.Pages
{
    /// <summary>
    /// DbService 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务，请取消注释以下行。 
    [System.Web.Script.Services.ScriptService]
    // ReSharper disable once RedundantNameQualifier
    public class DbService : System.Web.Services.WebService
    {
        // ReSharper disable once InconsistentNaming
        private static readonly Lazy<DrDbHelper> _dbInstance =
            new Lazy<DrDbHelper>(() => new DrDbHelper());
        public static DrDbHelper DbInstance => _dbInstance.Value;

        private static int _indexOutFileXls = 0;
        private static int _indexOutFileDocx = 0;

        #region 文件操作

        /// <summary>将传入的Excel文件传入数据库日志表</summary>
        /// <param name="userName">用户名</param>
        /// <param name="fileName">文件名（不包括目录）</param>
        /// <param name="deleteFirst">是否先删除旧数据</param>
        /// <returns></returns>
        [WebMethod]
        public string ImportExcel(string userName, string fileName, string deleteFirst)
        {
            if (string.IsNullOrWhiteSpace(userName)) return "Invalid Para";
            var originalDirectory = new DirectoryInfo(string.Format("{0}UploadFiles", Server.MapPath(@"\")));
            string fullPath = Path.Combine(originalDirectory.ToString(), "ExcelFiles\\");
            fullPath += fileName;

            bool bOk = false;
            try
            {
                var dt = ExcelHelper.Import(fullPath);

                string colNameRec = null,
                    colNameDate = null,
                    colNameProject = null,
                    colNameType = null,
                    colNameWorkHour = null,
                    colNameOvertime = null,
                    colNameRemark = null;
                foreach (DataColumn dc in dt.Columns)
                {
                    string colName = dc.ColumnName.ToUpper();
                    if (colName.Contains("日期") || colName.Contains("DATE"))
                        colNameDate = colName;
                    if (colName.Contains("描述"))
                        colNameRec = colName;
                    if (colName.Contains("项目"))
                        colNameProject = colName;
                    if (colName.Contains("类型"))
                        colNameType = colName;
                    if (colName.Contains("工作量"))
                        colNameWorkHour = colName;
                    if (colName.Contains("加班"))
                        colNameOvertime = colName;
                    if (colName.Contains("备注"))
                        colNameRemark = colName;
                }

                int count = dt.Rows.Count;
                List<string> texts = new List<string>(count);
                List<string> projectNames = new List<string>(count);
                List<string> typeNames = new List<string>(count);
                List<string> remarks = new List<string>(count);
                List<double> workHours = new List<double>(count);
                List<double> overtimes = new List<double>(count);
                List<string> recDates = new List<string>(count);

                foreach (DataRow dr in dt.Rows)
                {
                    texts.Add(dr[colNameRec].ToString());
                    projectNames.Add(dr[colNameProject].ToString());
                    typeNames.Add(dr[colNameType].ToString());
                    remarks.Add(dr[colNameRemark].ToString());
                    double workHour;
                    if (dr[colNameWorkHour] is DBNull ||
                        !double.TryParse(dr[colNameWorkHour].ToString(), out workHour))
                        workHour = 0;
                    double overtime;
                    if (dr[colNameOvertime] is DBNull ||
                        !double.TryParse(dr[colNameOvertime].ToString(), out overtime))
                        overtime = 0;
                    workHours.Add(workHour);
                    overtimes.Add(overtime);
                    string cellDate = dr[colNameDate].ToString();
                    DateTime dateRec = Convert.ToDateTime(cellDate);
                    string date = dateRec.ToString("yyyy-MM-dd");
                    recDates.Add(date);
                }
                bool delFirst = Convert.ToBoolean(deleteFirst);
                bOk = DbInstance.AddRecords(delFirst, userName, texts, projectNames, typeNames, remarks, workHours,
                    overtimes, recDates);
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(ImportExcel), e);
                return "Failed";
            }
            return bOk ? "Success" : "Failed";
        }

        /// <summary>得到待下载的Excel文件名称</summary>
        /// <param name="userName">用户名</param>
        /// <param name="startDate">起始日期</param>
        /// <param name="endDate">结束日期</param>
        /// <returns></returns>
        /// <remarks>不包括路径</remarks>
        /// <remarks>错误时返回空字符串</remarks>
        [WebMethod]
        public string GetExportExcelName(string userName, string startDate, string endDate)
        {
            if (string.IsNullOrWhiteSpace(userName)) return string.Empty;
            var fileName = "日报_" + _indexOutFileXls + ".xls";
            var outFileName = "日报-" + userName + ".xls";

            try
            {
                var dt = DbInstance.GetRecords(userName, startDate, endDate);
                if (dt == null) return string.Empty;

                var originalDirectory = new DirectoryInfo(string.Format("{0}UploadFiles", Server.MapPath(@"\")));
                string path = Path.Combine(originalDirectory.ToString(), "ExcelOutFiles\\");
                string fullPath = path + fileName;
                bool bOk = ExcelHelper.Export(dt, string.Empty, fullPath);
                if (!bOk) return string.Empty;
                string outFullPath = path + outFileName;
                File.Copy(fullPath, outFullPath, true);
                _indexOutFileXls++;
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(GetExportExcelName), e);
                return string.Empty;
            }
            return outFileName;
        }

        /// <summary>得到待下载的Word文件名称</summary>
        /// <param name="userName">用户名</param>
        /// <param name="startDate">起始日期</param>
        /// <param name="endDate">结束日期</param>
        /// <returns></returns>
        /// <remarks>不包括路径</remarks>
        /// <remarks>错误时返回空字符串</remarks>
        [WebMethod]
        public string GetExportDocxName(string userName, string startDate, string endDate)
        {
            if (string.IsNullOrWhiteSpace(userName)) return string.Empty;
            var fileName = "周工作总结_" + _indexOutFileDocx + ".docx";
            var outFileName = "周工作总结-" + userName + ".docx";

            try
            {
                var dt = DbInstance.GetRecords(userName, startDate, endDate);
                if (dt == null) return string.Empty;

                var originalDirectory = new DirectoryInfo(string.Format("{0}UploadFiles", Server.MapPath(@"\")));
                string path = Path.Combine(originalDirectory.ToString(), "DocxOutFiles\\");
                string fullPath = path + fileName;
                DateTime sd = DateTime.Parse(startDate);
                DateTime ed = DateTime.Parse(endDate);

                List<string> listWeekPlan = null;
                var dtime = DbInstance.GetMondayStr();
                if (DbInstance.ExistWeekPlan(userName, dtime))
                {
                    var dtWeekPlan = DbInstance.GetWeekPlan(userName, dtime);
                    if (dtWeekPlan != null && dtWeekPlan.Rows.Count > 0)
                    {
                        DataRow drWeekPlan = dtWeekPlan.Rows[0];
                        if (!(drWeekPlan["TEXT"] is DBNull) && !string.IsNullOrEmpty(drWeekPlan["TEXT"].ToString()))
                        {
                            listWeekPlan = new List<string>();
                            listWeekPlan.AddRange(drWeekPlan["TEXT"].ToString().Replace(", ", ",").Split(','));
                        }
                    }
                }

                bool bOk = DrDocxHelper.WriteDocx(userName, dt, sd, ed, fullPath, listWeekPlan);
                if (!bOk) return string.Empty;
                string outFullPath = path + outFileName;
                File.Copy(fullPath, outFullPath, true);
                _indexOutFileDocx++;
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(GetExportExcelName), e);
                return string.Empty;
            }
            return outFileName;
        }

        #endregion

        #region 登录操作

        [WebMethod]
        public string LoginUser(string name, string pass, string ip)
        {
            var res =  DbInstance.LoginUser(name, pass, ip);
            DbInstance.AddLoginInfo(name, ip);
            return res;
        }

        [WebMethod]
        public string RegUser(string name, string pass, string ip, string email)
        {
            var res = DbInstance.AddUser(name, pass, false, ip, email);
            DbInstance.AddLoginInfo(name, ip);
            return res;
        }

        #endregion

        #region 日志操作

        [WebMethod]
        public string GetAllRecords(string userName)
        {
            var dt = DbInstance.GetAllRecords(userName);
            return JsonConvert.SerializeObject(dt);
        }

        [WebMethod]
        public string GetProjectNames()
        {
            var list = DbInstance.GetProjectList();
            return JsonConvert.SerializeObject(list);
        }

        [WebMethod]
        public string GetProjectTypes()
        {
            var list = DbInstance.GetProjectTypeList();
            return JsonConvert.SerializeObject(list);
        }

        [WebMethod]
        public string AddRecord(string json)
        {
            try
            {
                // ReSharper disable once RedundantCast
                dynamic val = JsonConvert.DeserializeObject(json) as dynamic;
                if (val == null) return "Failed";
                string userName = val.userName;
                string recDate = val.recDate;
                string text = val.text;
                string projectName = val.projectName;
                string typeName = val.typeName;
                double workHour = Convert.ToDouble(val.workHour);
                double overtime = Convert.ToDouble(val.overtime);
                string remark = val.remark;

                if (!DbInstance.AddRecord(userName, text, projectName, typeName, remark, workHour, overtime, recDate))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(AddRecord), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string UpdateRecord(string json)
        {
            try
            {
                // ReSharper disable once RedundantCast
                dynamic val = JsonConvert.DeserializeObject(json) as dynamic;
                if (val == null) return "Failed";
                int id = Convert.ToInt32(val.id);
                string recDate = val.recDate;
                string text = val.text;
                string projectName = val.projectName;
                string typeName = val.typeName;
                double workHour = Convert.ToDouble(val.workHour);
                double overtime = Convert.ToDouble(val.overtime);
                string remark = val.remark;

                if (!DbInstance.UpdateRecord(id, recDate, text, projectName, typeName, remark, workHour, overtime))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(UpdateRecord), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string DeleteRecord(string id)
        {
            try
            {
                int intId = Convert.ToInt32(id);
                if (intId < 0) return "Failed";

                if (!DbInstance.DeleteRecord(intId))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(DeleteRecord), e);
                return "Failed";
            }
            return "Success";
        }

        #endregion

        #region 待办事项操作

        [WebMethod]
        public string GetAllTodos(string userName)
        {
            var dt = DbInstance.GetAllTodos(userName);
            if (dt == null) return string.Empty;

            List<JsonTodo> list = new List<JsonTodo>();
            foreach (DataRow dr in dt.Rows)
            {
                int status = Convert.ToInt32(dr["STATUS"]);
                DateTime fd = Convert.ToDateTime(dr["FINISH_DATE"]);

                list.Add(new JsonTodo()
                {
                    Id = Convert.ToInt32(dr["ID"]),
                    Text = dr["REC_TEXT"].ToString(),
                    FinishDate = fd.ToString("yyyy-MM-dd"),
                    Finished = status == 2
                });
            }
            return JsonConvert.SerializeObject(list);
        }

        [WebMethod]
        public string AddTodo(string userName, string text, string finishDate)
        {
            int id = -1;
            try
            {
                
                if (!DbInstance.AddTodo(out id, userName, text, finishDate, false))
                    return "-1";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(AddTodo), e);
                return "-1";
            }
            return id.ToString();
        }

        [WebMethod]
        public string UpdateTodo(string id, string text, string finishDate, string finished)
        {
            try
            {
                if (!DbInstance.UpdateTodo(Convert.ToInt32(id), text, finishDate, Convert.ToBoolean(finished)))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(UpdateTodo), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string UpdateChecked(string id, string finished)
        {
            try
            {
                if (!DbInstance.UpdateChecked(Convert.ToInt32(id), Convert.ToBoolean(finished)))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(UpdateTodo), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string DeleteTodo(string id)
        {
            try
            {
                int intId = Convert.ToInt32(id);
                if (intId < 0) return "Failed";

                if (!DbInstance.DeleteTodo(intId))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(DeleteTodo), e);
                return "Failed";
            }
            return "Success";
        }

        #endregion

        #region 每周计划操作

        [WebMethod]
        public string GetWeekPlans(string userName, bool ascSort = false)
        {
            var dt = DbInstance.GetAllWeekPlans(userName);
            if (dt == null) return string.Empty;

            List<JsonWeekPlanList> list = new List<JsonWeekPlanList>();
            foreach (DataRow dr in dt.Rows)
            {
                string date = dr["REL_DATE"].ToString().Replace(" 00:00:00", "").Replace(" 0:00:00", "");
                string text = dr["TEXT"] is DBNull ? string.Empty : dr["TEXT"].ToString();
                list.Add(new JsonWeekPlanList()
                {
                    UserName = userName,
                    Date = date,
                    RelDate = DateTime.Parse(date),
                    PlanList = text
                });
            }

            var nextMonday = DateTime.Parse(DbInstance.GetMondayStr());
            var lTmp = list.FirstOrDefault(l => l.RelDate == nextMonday);
            if (lTmp == null)
            {
                DbInstance.AddWeekPlan(userName, string.Empty);

                list.Add(new JsonWeekPlanList()
                {
                    UserName = userName,
                    Date = nextMonday.ToString("yyyy-MM-dd"),
                    RelDate = nextMonday,
                    PlanList = string.Empty
                });
            }

            if (ascSort) list.Sort((a, b) => a.RelDate.CompareTo(b.RelDate));
            else list.Sort((a,b)=> b.RelDate.CompareTo(a.RelDate));
            return JsonConvert.SerializeObject(list);
        }

        [WebMethod]
        public string AddWeekPlan(string userName, string text)
        {
            try
            {
                if (!DbInstance.AddWeekPlan(userName, text))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(AddWeekPlan), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string UpdateWeekPlan(string userName, string text, string date)
        {
            try
            {
                if (!DbInstance.UpdateWeekPlan(userName, text, date))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(UpdateWeekPlan), e);
                return "Failed";
            }
            return "Success";
        }

        [WebMethod]
        public string DeleteWeekPlan(string userName, string date)
        {
            try
            {
                if (!DbInstance.DeleteWeekPlan(userName, date))
                    return "Failed";
            }
            catch (Exception e)
            {
                LogHelper.WriteLog(nameof(DeleteWeekPlan), e);
                return "Failed";
            }
            return "Success";
        }

        #endregion

        #region 每日心情操作

        [WebMethod]
        public string GetDailyMods(string userName, string startDate, string endDate)
        {
            if (string.IsNullOrEmpty(userName)) return string.Empty;

            DateTime sd, ed;
            try
            {
                sd = DateTime.Parse(startDate);
                ed = DateTime.Parse(endDate);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(nameof(GetDailyMods), ex);
                return string.Empty;
            }

            var dic = DrNlpHelper.GetUserSentimentQuery(userName, sd, ed);
            return JsonConvert.SerializeObject(dic);
        }

        #endregion

        #region BearyChat交互

        /// <summary>接收来自BearyChart - Outgoing 的POST请求并回复</summary>
        /// <param name="token"></param>
        /// <param name="ts"></param>
        /// <param name="text"></param>
        /// <param name="trigger_word"></param>
        /// <param name="subdomain"></param>
        /// <param name="channel_name"></param>
        /// <param name="user_name"></param>
        /// <returns></returns>
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string BearyPost(string token, string ts, string text, string trigger_word, string subdomain, string channel_name, string user_name)
        {
            BearyResponse resp = new BearyResponse();
            resp.Text = "from Web service";
            var attach = new BearyAttachments();
            attach.Title = "标题1";
            attach.Text = "Something.";
            attach.Color = "#666666";
            attach.ListImage.Add(new BearyUrl() {Url = @"http://img1.skqkw.cn:888/2014/12/06/08/21ofdtyslqn-62877.jpg" });
            attach.ListImage.Add(new BearyUrl() { Url = @"http://img1.skqkw.cn:888/2014/11/26/08/o5u1t2j2m3a-73633.jpg" });
            resp.ListAttachment.Add(attach);
            string res = JsonConvert.SerializeObject(resp, Formatting.Indented);
            return res;
        }

        #endregion
    }
}
